package per.cy.common.util;

import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.StringReader;
import java.io.StringWriter;

/**
 * @author cy
 * date 2024/9/5
 */
public class XmlUtils {
    private XmlUtils() {
    }

    private static final Log log = LogFactory.get();

    /**
     * 将XML字符串解析为指定类的对象
     *
     * @param xmlStr 待解析的XML字符串
     * @param clz    目标对象的类
     * @param <T>    目标对象的类型
     * @return 解析后的对象
     * @throws RuntimeException 如果解析过程中发生错误
     */
    public static <T> T parseXml(String xmlStr, Class<T> clz) {
        try {
            // 创建JAXBContext对象，用于指定要解序列化的类
            JAXBContext jaxbContext = JAXBContext.newInstance(clz);
            // 创建解序列化器
            Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
            // 使用解序列化器将XML字符串转换为对象
            return (T) unmarshaller.unmarshal(new StringReader(xmlStr));
        } catch (JAXBException e) {
            // 记录解析错误日志
            log.error("parse xml error: {}", e.getMessage(), e);
            // 抛出运行时异常，提示解析错误
            throw new RuntimeException("parse xml error");
        }
    }


    /**
     * 将XML对象转换为字符串
     *
     * @param obj 需要转换的XML对象
     * @return 转换后的XML字符串
     * @throws RuntimeException 如果转换过程中发生错误
     */
    public static String xmlObj2Str(Object obj) {
        try {
            // 创建JAXB上下文，用于处理指定类型的对象
            JAXBContext jaxbContext = JAXBContext.newInstance(obj.getClass());
            // 创建Marshaller，用于将Java对象转换为XML
            Marshaller marshaller = jaxbContext.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
            // 创建StringWriter，用于存储转换后的XML字符串
            StringWriter writer = new StringWriter();
            // 将Java对象转换为XML，并存储到StringWriter中
            marshaller.marshal(obj, writer);
            // 返回转换后的XML字符串
            return writer.toString();
        } catch (JAXBException e) {
            // 记录转换过程中的异常信息
            log.error("xml 2 str error: {}", e.getMessage(), e);
            // 抛出运行时异常，表明转换过程中发生错误
            throw new RuntimeException("xml 2 str error");
        }
    }
}
